#!/bin/bash
# ThingsBoard 备份健康检查脚本
# 版本: 1.0.0

# 记录当前工作目录
CURRENT_DIR=$(pwd)

# 获取脚本所在目录的绝对路径
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)

# 根据脚本目录计算项目根目录路径
if [[ "$SCRIPT_DIR" == */scripts/monitoring ]]; then
  # 如果脚本位于scripts/monitoring目录中
  PROJECT_ROOT=$(cd "$SCRIPT_DIR/../.." && pwd)
elif [[ "$SCRIPT_DIR" == */scripts/* ]]; then
  # 如果脚本位于scripts目录或其他子目录中
  PROJECT_ROOT=$(echo "$SCRIPT_DIR" | sed 's|\(.*\)/scripts.*|\1|')
else
  # 否则假设当前目录是项目根目录
  PROJECT_ROOT=$(pwd)
fi

# 配置文件路径
CONFIG_FILE="$PROJECT_ROOT/config/backup_env.conf"

# 检查配置文件是否存在
if [ ! -f "$CONFIG_FILE" ]; then
  echo "错误: 配置文件不存在: $CONFIG_FILE"
  exit 1
fi

# 导入共用函数 - 使用绝对路径
COMMON_SCRIPT="$PROJECT_ROOT/scripts/common.sh"
if [ -f "$COMMON_SCRIPT" ]; then
  source "$COMMON_SCRIPT"
else
  echo "错误: 共用脚本不存在: $COMMON_SCRIPT"
  exit 1
fi

# 导入通知函数
NOTIFICATION_SCRIPT="$PROJECT_ROOT/scripts/monitoring/notification.sh"
if [ ! -f "$NOTIFICATION_SCRIPT" ]; then
    log_error "通知脚本不存在: $NOTIFICATION_SCRIPT"
    exit 1
fi

log_info "开始备份健康检查..."

# 检查系统状态
SYSTEM_STATUS=0

# 1. 检查PostgreSQL状态
log_info "检查PostgreSQL状态..."
if [ "$USE_DOCKER" = "true" ]; then
    # 检查Docker容器状态
    if ! docker ps | grep -q "$POSTGRES_CONTAINER_NAME"; then
        log_error "PostgreSQL容器未运行: $POSTGRES_CONTAINER_NAME"
        SYSTEM_STATUS=1
    else
        # 检查PostgreSQL连接
        if ! docker exec "$POSTGRES_CONTAINER_NAME" psql -U "$POSTGRES_SUPERUSER" -c "SELECT 1" > /dev/null 2>&1; then
            log_error "无法连接到PostgreSQL数据库"
            SYSTEM_STATUS=1
        else
            log_info "PostgreSQL容器运行正常"
        fi
    fi
else
    # 检查本地PostgreSQL服务
    if ! systemctl is-active --quiet postgresql; then
        log_error "PostgreSQL服务未运行"
        SYSTEM_STATUS=1
    else
        # 检查PostgreSQL连接
        if ! psql -U "$POSTGRES_SUPERUSER" -c "SELECT 1" > /dev/null 2>&1; then
            log_error "无法连接到PostgreSQL数据库"
            SYSTEM_STATUS=1
        else
            log_info "PostgreSQL服务运行正常"
        fi
    fi
fi

# 2. 检查ThingsBoard状态
log_info "检查ThingsBoard状态..."
TB_STATUS=0
check_thingsboard_service || TB_STATUS=$?

if [ $TB_STATUS -ne 0 ]; then
    log_error "ThingsBoard服务未运行"
    SYSTEM_STATUS=1
else
    log_info "ThingsBoard服务运行正常"
fi

# 3. 检查Nginx状态
log_info "检查Nginx状态..."
if [ "$USE_DOCKER" = "true" ]; then
    # 检查Docker容器状态
    if ! docker ps | grep -q "$NGINX_CONTAINER_NAME"; then
        log_error "Nginx容器未运行: $NGINX_CONTAINER_NAME"
        SYSTEM_STATUS=1
    else
        log_info "Nginx容器运行正常"
    fi
else
    # 检查本地Nginx服务
    if ! systemctl is-active --quiet nginx; then
        log_error "Nginx服务未运行"
        SYSTEM_STATUS=1
    else
        log_info "Nginx服务运行正常"
    fi
fi

# 4. 检查WAL-G是否已安装
log_info "检查WAL-G状态..."
if ! command -v wal-g &> /dev/null; then
    log_error "WAL-G未安装"
    SYSTEM_STATUS=1
else
    log_info "WAL-G已安装"
fi

# 5. 检查最近备份状态
log_info "检查最近备份状态..."

# 5.1 检查最近的全量备份
LATEST_FULL_BACKUP=$(find "$BACKUP_BASE_DIR/full" -maxdepth 1 -type d -name "thingsboard_full_*" | sort | tail -n 1)
if [ -z "$LATEST_FULL_BACKUP" ]; then
    log_warn "未找到全量备份"
else
    FULL_BACKUP_DATE=$(echo "$LATEST_FULL_BACKUP" | grep -o "full_[0-9]\{8\}_[0-9]\{6\}" | cut -d_ -f2-3)
    log_info "最近全量备份: $FULL_BACKUP_DATE"

    # 检查全量备份是否过期
    FULL_BACKUP_DAYS=$(( ( $(date +%s) - $(date -d "${FULL_BACKUP_DATE:0:8} ${FULL_BACKUP_DATE:9:2}:${FULL_BACKUP_DATE:11:2}:${FULL_BACKUP_DATE:13:2}" +%s) ) / 86400 ))

    if [ "$FULL_BACKUP_DAYS" -gt 7 ]; then
        log_warn "最近全量备份已过期 ($FULL_BACKUP_DAYS 天前)"
    else
        log_info "最近全量备份在有效期内 ($FULL_BACKUP_DAYS 天前)"
    fi
fi

# 5.2 检查最近的增量备份
LATEST_DIFF_BACKUP=$(find "$BACKUP_BASE_DIR/diff" -maxdepth 1 -type d -name "thingsboard_diff_*" | sort | tail -n 1)
if [ -z "$LATEST_DIFF_BACKUP" ]; then
    log_warn "未找到增量备份"
else
    DIFF_BACKUP_DATE=$(echo "$LATEST_DIFF_BACKUP" | grep -o "diff_[0-9]\{8\}_[0-9]\{6\}" | cut -d_ -f2-3)
    log_info "最近增量备份: $DIFF_BACKUP_DATE"

    # 检查增量备份是否过期
    DIFF_BACKUP_DAYS=$(( ( $(date +%s) - $(date -d "${DIFF_BACKUP_DATE:0:8} ${DIFF_BACKUP_DATE:9:2}:${DIFF_BACKUP_DATE:11:2}:${DIFF_BACKUP_DATE:13:2}" +%s) ) / 86400 ))

    if [ "$DIFF_BACKUP_DAYS" -gt 1 ]; then
        log_warn "最近增量备份已过期 ($DIFF_BACKUP_DAYS 天前)"
    else
        log_info "最近增量备份在有效期内 ($DIFF_BACKUP_DAYS 天前)"
    fi
fi

# 6. 检查磁盘空间
log_info "检查备份目录磁盘空间..."
BACKUP_DIR_USAGE=$(df -h "$BACKUP_BASE_DIR" | awk 'NR==2 {print $5}' | tr -d '%')

if [ "$BACKUP_DIR_USAGE" -gt 90 ]; then
    log_error "备份目录磁盘空间不足: $BACKUP_DIR_USAGE%"
    SYSTEM_STATUS=1
else
    log_info "备份目录磁盘空间充足: $BACKUP_DIR_USAGE%"
fi

# 7. 检查WAL归档状态
if [ "$WAL_ARCHIVE_ENABLED" = "true" ]; then
    log_info "检查WAL归档状态..."
    WAL_FILES_COUNT=$(find "$WAL_ARCHIVE_DIR" -type f -name "*.gz" 2>/dev/null | wc -l)
    log_info "当前WAL文件数量: $WAL_FILES_COUNT"

    # 如果数量为0，可能存在问题
    if [ "$WAL_FILES_COUNT" -eq 0 ]; then
        log_warn "未找到WAL文件，归档可能未正确配置"
    fi
fi

# 8. 总结健康状态
log_info "备份系统健康检查完成"

if [ $SYSTEM_STATUS -eq 0 ]; then
    log_info "所有系统组件状态正常"
else
    log_error "系统健康检查发现问题，请检查日志"

    if [ "$ENABLE_NOTIFICATIONS" = "true" ]; then
        send_notification "ThingsBoard备份系统健康检查警告" "系统健康检查发现问题，请检查日志"
    fi
fi

exit $SYSTEM_STATUS
